#ifndef QCSVSAVER_H
#define QCSVSAVER_H
#include <QString>
#include <QVector>
#include <fstream>
#include <string>
#include <vector>

template <typename T> class QCsvSaver {
public:
  explicit QCsvSaver(const std::string &p);
  virtual ~QCsvSaver();

  bool isValid() const;
  void reset();

  void write(const T &val);
  void write(const std::vector<T> &val);
  void write(const QVector<T> &val);

  void flush() { csv << std::flush; }

protected:
  std::string path;
  std::fstream csv;

private:
  static const std::ios_base::openmode om =
      std::fstream::out | std::fstream::trunc;
};

template <typename T>
QCsvSaver<T>::QCsvSaver(const std::string &p) : path(p), csv(path, om){};

template <typename T> bool QCsvSaver<T>::isValid() const {
  return csv.is_open();
}
template <typename T> void QCsvSaver<T>::reset() {
  if (csv.is_open()) {
    csv.close();
  }
  csv.open(path, om);
}

template <typename T> void QCsvSaver<T>::write(const T &val) {
  csv << val;
  csv << std::string("\n");
}
template <typename T> void QCsvSaver<T>::write(const std::vector<T> &val) {
  for (auto &v : val) {
    write(v);
  }
}
template <typename T> void QCsvSaver<T>::write(const QVector<T> &val) {
  for (auto it = val.begin(); it != val.end(); it++)
    write(*it);
}

template <typename T> QCsvSaver<T>::~QCsvSaver() {
  if (csv.is_open()) {
    csv << std::flush;
    csv.close();
  }
};
#endif